/**********************************************
* SFW_Stream.cpp
***********************************************/
#include "framework.h"

/**********************************************
* constructor
**********************************************/
SFW_Stream::SFW_Stream()
{
	offset = 0;
	length = 0;
	buffer = NULL;
}

SFW_Stream::SFW_Stream(int varlen)
{
	offset = 0;
	length = varlen;
	buffer = NULL;
}

SFW_Stream::~SFW_Stream()
{
	if(NULL != buffer)
	{
		free(buffer);
		buffer = NULL;
	}
}

/**********************************************
* member method
* initialize
**********************************************/
void SFW_Stream::initialize()
{
	if(length != 0)
	{
		buffer = (char*)malloc(length + 1);
		memset(buffer, 0x00, length + 1);
	}
	
	else
	{
		buffer = NULL;
	}
}

/**********************************************
* operator( << ) reload
**********************************************/
SFW_Stream& SFW_Stream::operator<<(unsigned int val)
{
	val = htonl(val);
	write((char*)&val, 4);
	return *this;
}

SFW_Stream& SFW_Stream::operator<<(short val)
{
	val = htons(val);
	write((char*)&val, 2);
	return *this;
}

SFW_Stream& SFW_Stream::operator<<(unsigned short val)
{
	val = htons(val);
	write((char*)&val, 2);
	return *this;
}

SFW_Stream& SFW_Stream::operator<<(char val)
{
	write(&val, 1);
	return *this;
}

SFW_Stream& SFW_Stream::operator<<(unsigned char val)
{
	write((char*)&val, 1);
	return *this;
}

SFW_Stream& SFW_Stream::operator<<(const string& val)
{
	write((char*)val.c_str(), val.size());
	return *this;
}

/**********************************************
* operator( >> ) reload
**********************************************/
SFW_Stream& SFW_Stream::operator>>(unsigned int& val)
{
	if(readInternal((char*)&val, 4))
	{
		val = ntohl(val);
	}
	
	return *this;
}

SFW_Stream& SFW_Stream::operator>>(short& val)
{
	if(readInternal((char*)&val, 2))
	{
		val = ntohs(val);
	}
	
	return *this;
}

SFW_Stream& SFW_Stream::operator>>(unsigned short& val)
{
	if(readInternal((char*)&val, 2))
	{
		val = ntohs(val);
	}
	
	return *this;
}

SFW_Stream& SFW_Stream::operator>>(char& val)
{
	readInternal((char*)&val, 1);
	
	return *this;
}

SFW_Stream& SFW_Stream::operator>>(unsigned char& val)
{
	readInternal((char*)&val, 1);
	
	return *this;
}

SFW_Stream& SFW_Stream::operator>>(string& val)
{
	char len = 0x00;
	
	/* get length */
	(*this)>>len;
	
	/* malloc */
	char* tmpbuf = (char*)malloc((int)len + 1);
	memset(tmpbuf, 0x00, len + 1);
	
	readInternal(tmpbuf, len);
	
	val = tmpbuf;
	
	free(tmpbuf);
	return *this;
}

void SFW_Stream::write(char* val, int len)
{
	if(length <= 0)
	{
		LOG_FATAL("buffer length error(@@@)!");
		return ;
	}
	
	if(offset + len > length)
	{
		LOG_FATAL("buffer overflow error(@@@)!");
		return ;
	}
	
	memcpy(buffer + offset, val, len);
	offset += len;
}

int SFW_Stream::read(char* val, int len)
{
	int realLen = (length - offset) > len ? len : (length - offset);
	
	memcpy(val, buffer + offset, realLen);
	return realLen;
}

bool SFW_Stream::readInternal(char* val, int len)
{
	int readBytes = read(val , len);
	
	offset += len;
	
	return (readBytes == len ? true : false);
}

void SFW_Stream::readWithoutMove(char* val, int len)
{
	if(read(val, len) < len) val = NULL;
}

